<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
 <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9">
 <TITLE>The VFLib Graph Matching Library, version 2.0: Using VFLib: a quick tour : Loading and saving graphs</TITLE>
 <LINK HREF="vflib-12.html" REL=next>
 <LINK HREF="vflib-10.html" REL=previous>
 <LINK HREF="vflib.html#toc3" REL=contents>
</HEAD>
<BODY>
<A HREF="vflib-12.html">Next</A>
<A HREF="vflib-10.html">Previous</A>
<A HREF="vflib.html#toc3">Contents</A>
<HR>
<H2>3.6 Loading and saving graphs</H2>

<P>
<P>In order to load and save graphs from files, we have
provided two classes derived from <CODE>ARGLoader</CODE>. The
first, <CODE>BinaryGraphLoader</CODE>, is devoted to
unattributed graphs, and adopts the binary file format
employed for the 
<A HREF="http://amalfi.dis.unina.it/graph">Graph Database</A>.
The second, <CODE>StreamARGLoader</CODE>, is a template class which
employs C++ input/output streams and overloaded stream
operators to read and write graphs from/to text files.
Both the classes are defined in <CODE>argloader.h</CODE> .
<P>In section 
<A HREF="vflib-12.html#ClassReference">VFLib class reference</A>
a detailed description of the file formats will be presented. Here
we will show some examples of the use of these two classes.
<P>Let us start with <CODE>BinaryGraphLoader</CODE>. The constructor of this
class requires an <CODE>istream</CODE> object, which must be open using
the <CODE>ios::binary</CODE> mode: 
<P>
<BLOCKQUOTE><CODE>
<HR>
<PRE>
#include &lt;iostream>
#include &lt;fstream>

using namespace std;
 
#include "argraph.h"
#include "argloader.h"
 
 
int main()
  { // First, open the file in binary mode
    ifstream in("graph.bin", ios::in | ios::binary);

    // Second, create a BinaryGraphLoader
    BinaryGraphLoader loader(in);

    // Now a graph can be constructed
    Graph g(&amp;loader);
 
    // ... to be continued ...
</PRE>
<HR>
</CODE></BLOCKQUOTE>
<P>
<P>A graph, represented either as an object of class <CODE>Graph</CODE>, or
as an <CODE>ARGLoader</CODE>, can be saved in the same format using the
static method <CODE>write</CODE>. 
<P>
<BLOCKQUOTE><CODE>
<HR>
<PRE>

   // ... suppose that a graph g has been constructed ...

   // Open a binary file
   ofstream out("outfile.bin", ios::out | ios::binary);

   // Write the graph
   GraphBinaryLoader::write(out, g);

   // Close the file
   out.close();

   // ... to be continued ...
</PRE>
<HR>
</CODE></BLOCKQUOTE>
<P>Remember that this class does not
consider node/edge attributes!
<P>Now, let us turn our attention to <CODE>StreamARGLoader&lt;N,E></CODE>. 
This is a template class for reading and writing graphs with node
attributes of type <CODE>N</CODE> and edge attributes of type <CODE>E</CODE>.
<P>As we have said previously, it is responsibility of the <CODE>ARGLoader</CODE>
to allocate the data structures for storing the attributes. 
<CODE>StreamARGLoader</CODE> perform this task with the help of an <CODE>Allocator</CODE>
instance. <CODE>Allocator</CODE> is an abstract template class which provide
an <CODE>Allocate</CODE> method for creating a new attribute. 
The template class <CODE>NewAllocator</CODE> is an implementation of <CODE>Allocator</CODE>
that uses the <CODE>new</CODE> operator for allocating the attribute.
Both <CODE>Allocator</CODE> and <CODE>NewAllocator</CODE> are defined in <CODE>allocpool.h</CODE>.
<P>Besides creating a suitable allocator, you need to override the
operator <CODE>&gt;&gt; for reading graphs and the operator <CODE>&lt;&lt;</CODE>
for writing, if the types of your attributes do not already support stream I</CODE>O.
<P>For example, let us reconsider the case in which the node attributes
represent points in the plane, and there are no edge attributes.
<P>First, you have to define the attribute classes, with the corresponding
I/O operators. Notice that you will need an empty class for the 
edge attribute. 
<P>
<BLOCKQUOTE><CODE>
<HR>
<PRE>
#include &lt;iostream>
#include &lt;fstream>

#include &lt;argraph.h>
#include &lt;argloader.h>
#include &lt;allocpool.h>


// 
// Define class Point, with its I/O operators
//
class Point
  { public:
      float x, y;
  };

istream&amp; operator>>(istream&amp; in, Point &amp;p)
  { in >> p.x >> p.y;
    return in;
  }

ostream&amp; operator&lt;&lt;(ostream&amp; out, Point &amp;p)
  { out &lt;&lt; p.x &lt;&lt; ' ' &lt;&lt; p.y;
    return out;
  }

// 
// Define class Empty, with its I/O operators
//
class Empty
  {
  };

istream&amp; operator>>(istream&amp; in, Empty &amp;)
  { // Do nothing!
    return in;
  }

ostream&amp; operator&lt;&lt;(ostream&amp; out, Empty &amp;)
  { // Do nothing!
    return out;
  }
</PRE>
<HR>
</CODE></BLOCKQUOTE>
<P>Now, you have first to create the two allocators (one for nodes
and one for edges), and then a <CODE>Stream&shy;ARGLoader</CODE> object. Notice that
for the edges we have used a <CODE>NullAllocator</CODE>, which does no
allocation at all!
<P>
<BLOCKQUOTE><CODE>
<HR>
<PRE>
int main()
  { // Create the allocators
    NewAllocator&lt;Point> node_allocator;
    NullAllocator&lt;Empty> edge_allocator;

    // Open the file
    ifstream in("graph.txt");


    // Create the ARGLoader
    StreamARGLoader&lt;Point, Empty> loader(&amp;node_allocator, 
                                         &amp;edge_allocator, 
                                         in);

    // Build the graph
    ARGraph&lt;Point, Empty> graph(&amp;loader);

    //......
</PRE>
<HR>
</CODE></BLOCKQUOTE>
<P>Similarly to the <CODE>GraphBinaryLoader</CODE> class, also <CODE>StreamARGLoader</CODE>
provides a static <CODE>write</CODE> method to write out a graph in the
corresponding format:
<P>
<BLOCKQUOTE><CODE>
<HR>
<PRE>

   // ... suppose that a graph g has been constructed ...

   // Open a text file
   ofstream out("outfile.txt");

   // Write the graph
   StreamARGLoader::write(out, g);

   // Close the file
   out.close();

   // ... to be continued ...
</PRE>
<HR>
</CODE></BLOCKQUOTE>
<P>
<P>
<HR>
<A HREF="vflib-12.html">Next</A>
<A HREF="vflib-10.html">Previous</A>
<A HREF="vflib.html#toc3">Contents</A>
</BODY>
</HTML>
